package com.hello.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hello.sky.enmu.CommonError;
import com.hello.sky.exception.SkyException;
import com.hello.sky.mapper.UserMapper;
import com.hello.sky.model.dto.DataOverViewQueryDTO;
import com.hello.sky.model.dto.UserLoginDTO;
import com.hello.sky.model.entity.User;
import com.hello.sky.model.vo.UserLoginVO;
import com.hello.sky.model.vo.UserReportVO;
import com.hello.sky.properties.WeChatProperties;
import com.hello.sky.service.UserService;
import com.hello.sky.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;


import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * <p>
 * 用户信息 服务实现类
 * </p>
 *
 * @author D
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private WeChatProperties weChatProperties;

    private final String wxLogin = "https://api.weixin.qq.com/sns/jscode2session";

    @Override
    public UserLoginVO wxLogin(UserLoginDTO dto) {
        try {
            String openId = getOpenId(dto.getCode());

            //是否注册过,没有查到就插入
            User user = baseMapper.selectByOpenId(openId);
            if (user == null){
                user = new User();
                user.setOpenid(openId);
                user.setName("u_"+openId.substring(5,10));
                user.setCreateTime(LocalDateTime.now());
                baseMapper.insert(user);
            }

            //封装token
            HashMap<Object, Object> cliams = new HashMap<>();
            cliams.put("userId", user.getId());
            String jwt = JwtUtil.getJwt(cliams);

            //封装vo返回
            UserLoginVO userLoginVO = new UserLoginVO();
            userLoginVO.setId(user.getId());
            userLoginVO.setOpenid(userLoginVO.getOpenid());
            userLoginVO.setToken(jwt);
            return userLoginVO;
        } catch (IOException e) {
            throw SkyException.cast("获取微信用户信息失败");
        }

    }



    public String getOpenId(String code) throws IOException {
        //封装uri
        String appid = weChatProperties.getAppid();
        String secret = weChatProperties.getSecret();
        ArrayList<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("appid", appid));
        params.add(new BasicNameValuePair("secret", secret));
        params.add(new BasicNameValuePair("js_code", code));
        params.add(new BasicNameValuePair("grant_type", "authorization_code"));

        //封装url
        URI uri;
        try {
            uri = new URIBuilder(new URI(wxLogin))
                    .addParameters(params)
                    .build();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        HttpGet get = new HttpGet(uri);

        //发送请求
        CloseableHttpClient client = HttpClients.createDefault();
        CloseableHttpResponse response = client.execute(get);

        //解析返回数据
        HttpEntity entity = response.getEntity();
        String json = EntityUtils.toString(entity);
        JSONObject jsonObject = JSON.parseObject(json);
        if (!jsonObject.containsKey("openid")){
            SkyException.cast(CommonError.PARAMS_ERROR);
        }
        String openid = jsonObject.get("openid").toString();
        client.close();
        response.close();
        return openid;
    }
}
